package com.zhiziai.aiproxy.utils;

import cn.hutool.core.lang.UUID;
import org.springframework.web.multipart.MultipartFile;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author: liuxinyu06
 * @Date: 2023-04-04
 * @Description:
 */
public class FileUtil {

    /**
     * 将图片转为file
     *
     * @param url 图片url
     * @return File
     * @author dyc
     * date:   2020/9/4 14:54
     */
    public static File getFile(String url,String prefix) throws Exception {
        //对本地文件命名
        String fileName = ".png";
        File file = null;

        URL urlfile;
        InputStream inStream = null;
        OutputStream os = null;
        try {
            file = File.createTempFile(prefix,fileName);
            //下载
            urlfile = new URL(url);
            inStream = urlfile.openStream();
            os = new FileOutputStream(file);

            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = inStream.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != os) {
                    os.close();
                }
                if (null != inStream) {
                    inStream.close();
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return file;
    }

    /**
     * 将图片转为file
     *
     * @param url 图片url
     * @return File
     * @author dyc
     * date:   2020/9/4 14:54
     */
    public static File getFile(String url) throws Exception {
        //对本地文件命名
        String fileName = ".png";
        File file = null;

        URL urlfile;
        InputStream inStream = null;
        OutputStream os = null;
        try {
            file = File.createTempFile(UUID.fastUUID() +"",fileName);
            //下载
            urlfile = new URL(url);
            inStream = urlfile.openStream();
            os = new FileOutputStream(file);

            int bytesRead = 0;
            byte[] buffer = new byte[8192];
            while ((bytesRead = inStream.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != os) {
                    os.close();
                }
                if (null != inStream) {
                    inStream.close();
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        return file;
    }

    /**
     * 用缓冲区来实现这个转换, 即创建临时文件
     * 使用 MultipartFile.transferTo()
     *
     * @param multipartFile
     * @return
     */
    public static File transferToFile(MultipartFile multipartFile) throws IOException {
        String originalFilename = multipartFile.getOriginalFilename();
        String prefix = originalFilename.split("\\.")[0];
        String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
        File file = File.createTempFile(MD5Util.calcMD5(prefix), suffix);
        multipartFile.transferTo(file);
        return file;
    }

    /**
     * 大文件分片写入本地
     *
     * @throws IOException
     */
    public static List<File> filePart(File sourceFile,int partSize) throws IOException {
        List<File> partFiles = new ArrayList<>();
        // 设定文件分块大小,设定100M
        long chunkSize = 1024 * 1024 * partSize;
        // 分块数量
        long chunkNum = (long) Math.ceil(sourceFile.length() * 1.0 / chunkSize);
        if(chunkNum<=0){
            chunkNum=1;
        }
        // 设置缓冲区
        byte[] bytes = new byte[1024];  // 和下面方式创建byte[]效率基本一样
//        byte[] bytes = new byte[(int) sourceFile.length()];
        BufferedInputStream fis = new BufferedInputStream(new FileInputStream(sourceFile));
        String suffix = cn.hutool.core.io.FileUtil.getSuffix(sourceFile);
        // 开始分块
        for (int i = 1; i <= chunkNum; i++) {
            // 创建分块文件
            File file = File.createTempFile(sourceFile.getParent(), i +"." + suffix);
            // 向分块文件中写数据
            BufferedOutputStream fos = new BufferedOutputStream(new FileOutputStream(file));
            int len = -1;
            while ((len = fis.read(bytes)) != -1) {
                fos.write(bytes, 0, len); // 写入数据
                if(file.length()>chunkSize){
                    break;
                }
            }
            partFiles.add(file);
            fos.close();
        }
        fis.close();
        return partFiles;
    }

    //file需要分片的文件，splitNum:要分几片，currentDir：分片后存放的位置，splitSize：按多大分片
    public static List<File> nioSpilt(File file, int splitNum,long splitSize) throws Exception {
        List<File> files = new ArrayList<>();
        String suffix = cn.hutool.core.io.FileUtil.getSuffix(file.getName());
        FileInputStream fis = new FileInputStream(file);
        FileChannel inputChannel = fis.getChannel();
        FileOutputStream fos;
        FileChannel outputChannel;
        long startPoint = 0;
        for (int i = 1; i <= splitNum; i++) {
            String splitFileName = i+"." +suffix;
            File splitFile = new File(splitFileName);
            splitFile.createNewFile();
            fos = new FileOutputStream(splitFileName);
            outputChannel = fos.getChannel();
            inputChannel.transferTo(startPoint, splitSize, outputChannel);
            startPoint += splitSize;
            files.add(splitFile);
            outputChannel.close();
            fos.close();
        }
        inputChannel.close();
        fis.close();
        return files;
    }


}
